/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package com.cj.user.service.impl;


import cn.hutool.core.lang.TypeReference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cj.user.dao.SysMenuDao;
import com.cj.user.entity.Category;
import com.cj.user.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service("sysMenuService")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuDao, Category> implements SysMenuService {

	@Autowired
	private RedisTemplate redisTemplate;

	@Override
	public List<Category> findCategory() {
//		synchronized (this) {
//			return this.findCategoryData();
//		}

		// 分布式锁
		Boolean category = redisTemplate.opsForValue().setIfAbsent("lock", "123", 30, TimeUnit.SECONDS);
		if(category) {
			List<Category> categoryData = this.findCategoryData();
			redisTemplate.delete("lock");

			return categoryData;
		}else {
			// 自旋
			return this.findCategory();
		}
	}

	public List<Category> findCategoryData() {
		// 看缓存是否有数据
		String categorieCache = String.valueOf(redisTemplate.opsForValue().get("category"));
		List<Category> categoriesCache = JSON.parseObject(categorieCache, new TypeReference<List<Category>>(){});
		if(categoriesCache != null && categoriesCache.size() > 0) {
			// 缓存有数据
			return categoriesCache;
		}

		// 查询所有类别
		List<Category> categories = this.list(null);
		System.out.println("--------------------------查询数据库------------------------");
		// 组装树形结构
		List<Category> level1Menus = categories.stream().filter(category ->
				Objects.equals(category.getParentCid(), "0") && Objects.equals(category.getShowStatus(), 2)
		).map(menu -> {
			menu.setChildren(getChildrens(menu, categories));
			return menu;
			// 排序
		}).sorted(Comparator.comparingInt(firstMenu -> (firstMenu.getSort() == null ? 0 : firstMenu.getSort()))
		).collect(Collectors.toList());

		// 更新缓存
		redisTemplate.opsForValue().set("category", JSONObject.toJSONString(level1Menus), 1, TimeUnit.HOURS);

		return level1Menus;
	}

	/**
	 * 递归查找所有菜单的子菜单
	 * @param root
	 * @param categories
	 * @return
	 */
	private List<Category> getChildrens(Category root, List<Category> categories) {
		List<Category> categoryList = categories.stream().filter(category ->
				// 子菜单匹配
				Objects.equals(category.getParentCid(), String.valueOf(root.getCatId())) && Objects.equals
						(category.getShowStatus(), 2)
		).map(category -> {
			// children赋值
			category.setChildren(getChildrens(category, categories));
			return category;
			// 排序
		}).sorted(Comparator.comparingInt(firstMenu -> (firstMenu.getSort() == null ? 0 : firstMenu.getSort()))
		).collect(Collectors.toList());

		return categoryList;
	}
}
